package com.encryptdemo.encrypt.aop;

import cn.hutool.core.io.IoUtil;
import com.encryptdemo.encrypt.annotation.EncryptDecrypt;
import com.encryptdemo.encrypt.util.AESUtil;
import org.springframework.core.MethodParameter;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.RequestBodyAdviceAdapter;

import java.io.InputStream;
import java.lang.reflect.Type;

@ControllerAdvice
public class DecryptAdvice extends RequestBodyAdviceAdapter {

    private static final String SECRET_KEY = "1234567890123456"; // 16字节密钥

    @Override
    public boolean supports(MethodParameter methodParameter, Type targetType, Class<? extends HttpMessageConverter<?>> converterType) {
        // 判断方法是否标记了 @EncryptDecrypt 注解
        return methodParameter.hasMethodAnnotation(EncryptDecrypt.class);
    }

    @Override
    public HttpInputMessage beforeBodyRead(HttpInputMessage inputMessage, MethodParameter parameter, Type targetType,
                                           Class<? extends HttpMessageConverter<?>> converterType) {
        try {
            // 读取原始请求体
            InputStream inputStream = inputMessage.getBody();
            String encryptedData = IoUtil.readUtf8(inputStream);

            // 解密数据
            String decryptedData = AESUtil.decryptByAes(encryptedData,SECRET_KEY);

            // 返回解密后的数据包装为 HttpInputMessage
            return new CustomHttpInputMessage(decryptedData, inputMessage.getHeaders());
        } catch (Exception e) {
            throw new RuntimeException("Error during decryption", e);
        }
    }

    // 自定义 HttpInputMessage，用于包装解密后的数据
    private static class CustomHttpInputMessage implements HttpInputMessage {
        private final InputStream body;
        private final org.springframework.http.HttpHeaders headers;

        public CustomHttpInputMessage(String body, org.springframework.http.HttpHeaders headers) {
            this.body = new java.io.ByteArrayInputStream(body.getBytes());
            this.headers = headers;
        }

        @Override
        public InputStream getBody() {
            return body;
        }

        @Override
        public org.springframework.http.HttpHeaders getHeaders() {
            return headers;
        }
    }
}
